package cn.org.tpeach.nosql.controller;

import cn.org.tpeach.nosql.bean.DicBean;
import cn.org.tpeach.nosql.enums.RedisTreeType;
import cn.org.tpeach.nosql.framework.ServiceProxy;
import cn.org.tpeach.nosql.redis.bean.RedisKeyData;
import cn.org.tpeach.nosql.redis.bean.RedisKeyInfo;
import cn.org.tpeach.nosql.redis.controller.BaseController;
import cn.org.tpeach.nosql.redis.controller.ResultRes;
import cn.org.tpeach.nosql.redis.service.IRedisConnectService;
import cn.org.tpeach.nosql.service.ICommonService;
import cn.org.tpeach.nosql.tools.ConfigParserUtils;
import cn.org.tpeach.nosql.tools.ReflectUtil;
import cn.org.tpeach.nosql.tools.StringUtils;
import cn.org.tpeach.nosql.view.JavaFxUtil;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import lombok.Getter;
import lombok.Setter;

import java.net.URL;
import java.text.DecimalFormat;
import java.util.ResourceBundle;

/**
 * @author tyz
 * @Title: TableRowInfoToKeyController
 * @ProjectName Redis-Lettuce-Parent
 * @Description:
 * @date 2020-06-05 20:06
 * @since 1.0.0
 */
@Getter
public class TableRowInfoToKeyController implements Initializable {
    private final IRedisConnectService redisConnectService = ServiceProxy.getBeanProxy("redisConnectService", IRedisConnectService.class);
    private final ICommonService commonService = ServiceProxy.getBeanProxy("commonService", ICommonService.class);

    @FXML
    private Text keyRowScoreOrFieldText;
    @FXML
    private Text keyRowValueText;
    @FXML
    private ComboBox<DicBean> keyRowScoreOrFieldComboBox;
    @FXML
    private ComboBox<DicBean> keyRowValueComboBox;
    @FXML
    private TextArea keyRowScoreOrFieldTextArea;
    @FXML
    private TextArea keyRowValueTextArea;
    @FXML
    private GridPane keyRowGridPane;
    @FXML
    private HBox keyRowScoreOrFieldHbox;
    @FXML
    private HBox keyRowValueHbox;

    @FXML
    private HBox keyRowScoreOrFieldSizeHbox;
    @FXML
    private HBox keyRowValueSizeHbox;
    @FXML
    private Label keyRowScoreOrFieldSizeLabel;
    @FXML
    private Label keyRowValueSizeLabel;


    @Setter
    private Button configButton;
    private Boolean left;
    private String scoreOrField;
    private String value;
    private RedisKeyInfo redisKeyInfo;
    private RedisKeyData redisKeyData;

    @Override
    public void initialize(URL location, ResourceBundle resources) {


    }

    /**
     *
     * @param redisKeyInfo
     * @param data
     * @param isLeft
     * @param isShow
     */
    public void init(RedisKeyInfo redisKeyInfo, RedisKeyData data,Boolean isLeft,boolean isShow){
        RedisKeyInfo keyInfo = new RedisKeyInfo();
        ReflectUtil.copyProperties(redisKeyInfo,keyInfo);
        this.redisKeyInfo = keyInfo;
        this.redisKeyData = data;
        configButton.setVisible(!isShow);
        configButton.setDisable(true);
        left = isLeft;
        if(data != null){
            keyRowValueTextArea.setText(StringUtils.showHexStringValue(ConfigParserUtils.getInstance().byteToStr(data.getValue())));
            value = keyRowValueTextArea.getText();
            keyRowValueTextArea.setUserData(keyRowValueTextArea.getText());
            keyRowValueTextArea.getProperties().put("text",keyRowValueTextArea.getText());
            keyRowValueTextArea.getProperties().put("textByte",data.getValue());
            keyRowValueSizeLabel.setText(StringUtils.getLengthHumman(data.getValue().length));

        }

        switch (redisKeyInfo.getType()){
            case SET:
            case LIST:
                keyRowGridPane.getChildren().clear();
                keyRowGridPane.add(keyRowValueHbox,4,0,3,1);
                keyRowGridPane.add(keyRowValueText,0,5,1,1);
                keyRowGridPane.add(keyRowValueTextArea,1,1,6,11);
                keyRowGridPane.add(keyRowValueSizeHbox,1,0,2,1);
                keyRowGridPane.setVgap(20);
                keyRowGridPane.setPrefSize(700,400 );

                break;
            case ZSET:
                if(data != null){
                    keyRowScoreOrFieldTextArea.setText(StringUtils.decimalFormat.format(data.getScore()));
                    scoreOrField = keyRowScoreOrFieldTextArea.getText();
                    keyRowScoreOrFieldTextArea.setUserData(scoreOrField);
                    keyRowScoreOrFieldTextArea.getProperties().put("text",scoreOrField);
                    byte[] bytes = ConfigParserUtils.getInstance().strToByte(scoreOrField);
                    keyRowScoreOrFieldTextArea.getProperties().put("textByte",bytes);
                    keyRowScoreOrFieldSizeLabel.setText(StringUtils.getLengthHumman(bytes.length));
                }
                keyRowScoreOrFieldText.setText("Score:");
                break;
            case HASH:
                if(data != null){
                    keyRowScoreOrFieldTextArea.setText(StringUtils.showHexStringValue(ConfigParserUtils.getInstance().byteToStr(data.getField())));
                    scoreOrField = keyRowScoreOrFieldTextArea.getText();
                    keyRowScoreOrFieldTextArea.setUserData(scoreOrField);
                    keyRowScoreOrFieldTextArea.getProperties().put("text",scoreOrField);
                    keyRowScoreOrFieldTextArea.getProperties().put("textByte",data.getField());
                    keyRowScoreOrFieldSizeLabel.setText(StringUtils.getLengthHumman(data.getField().length));
                }
                keyRowScoreOrFieldText.setText("Field:");
                break;
            default:
                break;
        }
        keyRowScoreOrFieldTextArea.setEditable(!isShow);
        keyRowValueTextArea.setEditable(!isShow);
        if(data != null && isShow){
            DicBean plainText = new DicBean("1", "PlainText");
            keyRowValueComboBox.getItems().addAll(
                    plainText,
                    new DicBean("2", "Json"),
                    new DicBean("3", "Hex Plain"),
                    new DicBean("4", "Hex")
            );
            keyRowScoreOrFieldComboBox.getItems().addAll(keyRowValueComboBox.getItems());
            keyRowValueComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) ->{
                    commonService.getSelectDicText(keyRowValueTextArea,newValue,configButton);
                    if(isShow){
                        keyRowValueTextArea.setEditable(false);
                    }
            } );
            keyRowScoreOrFieldComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) ->{
                commonService.getSelectDicText(keyRowScoreOrFieldTextArea,newValue,configButton);
                if(isShow){
                    keyRowValueTextArea.setEditable(false);
                }
            } );

            keyRowValueComboBox.setValue(plainText);
            keyRowScoreOrFieldComboBox.setValue(plainText);

        }else{
            keyRowScoreOrFieldComboBox.setVisible(false);
            keyRowValueComboBox.setVisible(false);
        }



        keyRowValueTextArea.textProperty().addListener((observable, oldValue, newValue) -> {
            configButton.setDisable(!check());
        });
        keyRowScoreOrFieldTextArea.textProperty().addListener((observable, oldValue, newValue) -> {
            configButton.setDisable(!check());
        });
    }

    private boolean check(){
        if(redisKeyData == null){
            if(RedisTreeType.LIST.equals(redisKeyInfo.getType()) || RedisTreeType.SET.equals(redisKeyInfo.getType())){
                return StringUtils.isNotEmpty(keyRowValueTextArea.getText());
            }
            return StringUtils.isNotEmpty(keyRowValueTextArea.getText())
                    && StringUtils.isNotEmpty(keyRowScoreOrFieldTextArea.getText());
        }
        if(RedisTreeType.LIST.equals(redisKeyInfo.getType()) || RedisTreeType.SET.equals(redisKeyInfo.getType())){
            return StringUtils.isNotEmpty(keyRowValueTextArea.getText()) && !StringUtils.equals(keyRowValueTextArea.getText(),value);
        }
        boolean v= StringUtils.isNotEmpty(keyRowValueTextArea.getText())  && StringUtils.isNotEmpty(keyRowScoreOrFieldTextArea.getText()) ;
        return v && (!StringUtils.equals(keyRowValueTextArea.getText(),value) || !StringUtils.equals(keyRowScoreOrFieldTextArea.getText(),scoreOrField));


    }

    public boolean submit(){

        RedisKeyInfo newKeyInfo = new RedisKeyInfo();
        ReflectUtil.copyProperties(redisKeyInfo, newKeyInfo);
        switch (redisKeyInfo.getType()) {
            case ZSET:
                try {
                    newKeyInfo.setScore(Double.valueOf(keyRowScoreOrFieldTextArea.getText()));
                } catch (NumberFormatException ez) {
                    JavaFxUtil.showMessageErrorDialog(null,null,"请输入正确的分数");
                    return false;
                }
            case STRING:
            case LIST:
            case SET:
                newKeyInfo.setValue(ConfigParserUtils.getInstance().strToByte(keyRowValueTextArea.getText()));
                break;
            case HASH:
                newKeyInfo.setField(ConfigParserUtils.getInstance().strToByte(keyRowScoreOrFieldTextArea.getText()));
                newKeyInfo.setValue(ConfigParserUtils.getInstance().strToByte(keyRowValueTextArea.getText()));
                break;
            default:
                break;
        }
        if(redisKeyData == null){
            ResultRes<Long> res = BaseController.dispatcher(() -> redisConnectService.addRowKeyInfo(newKeyInfo,left));
            if(res.isRet()){
                JavaFxUtil.showMessageInfoDialog(null,null,"保存成功");
               return true;
            }else{
                JavaFxUtil.showMessageErrorDialog(null,null,res.getMsg());
            }
        }else{
            newKeyInfo.setIndex(redisKeyData.getIndex());
            redisKeyInfo.setValue(redisKeyData.getValue());
            redisKeyInfo.setField(redisKeyData.getField());
            redisKeyData.setScore(redisKeyData.getScore());
            ResultRes<RedisKeyInfo> res = BaseController.dispatcher(() -> redisConnectService.updateKeyInfo(newKeyInfo, redisKeyInfo));
            if(res.isRet()){
                JavaFxUtil.showMessageInfoDialog(null,null,"保存成功");
                return true;
            }else{
                JavaFxUtil.showMessageErrorDialog(null,null,res.getMsg());
            }
        }
        return false;
    }

}
